import Nifi from "../../nifi";
import { h } from "vue";
import {DEFAULT_CELL_NAME,DEFAULT_NODE_PORTS} from "../metadata"
import {diff, pickData} from "../../util"
import markup from "./markup"
import { Cell } from "@ui/pack-antv-x6";
import { ElMessage } from "element-plus";
//
import FormElem from "./form.vue"
import ContextmenuElem from "./contextmenu.vue"
import {t} from "../../i18n/index"

const KEYS:[key:string,sk?:any][] = [
    ['id'],
    ['label','component.name'],
    ["position.x","position.x"],
    ["position.y","position.y"],
    ['version','revision.version'],
    ['invalidCount'],
    ['runningCount'],
    ['stoppedCount'],
    ['disabledCount'],
];


const name = DEFAULT_CELL_NAME.processGroups.en;
const shape = `node-${name}`;

export default (nifi:Nifi) => {
    //
    // 注册 节点
    nifi.graph.registerNode(shape, markup);

    // init
    const init = (tds:any[] | any) => {
        const res:any[] = [];
        for(const td of new Array().concat(tds)){
            if (!td) continue;
            nifi.cells.set(td)
            const md = {...pickData(td,KEYS),name,shape};
            // 判定是否显示连接桩
            const ports:any = {
                groups:DEFAULT_NODE_PORTS.groups,
                items:[]
            }
            if(td.inputPortCount > 0) {
                ports.items.push(DEFAULT_NODE_PORTS.items[0])
            }
            if(td.outputPortCount > 0) {
                ports.items.push(DEFAULT_NODE_PORTS.items[1])
            }
            //
            md.ports = ports;
            res.push(md);
        }
        return res;
    }

    const add = async (d:any) => {
        const data = { component:{...d}, disconnectedNodeAcknowledged: false, revision: { clientId: nifi.flow.clientId, version: 0 } }
        //
        const td = await nifi.cells.addCell(name, data)
        const md = init(td)[0];
        if(md){
            nifi.graph?.addNode(md);
        }
    }
    // 刷新单个元素 对比 目标数据和本地数据，只做差异刷新
    const update = (td:any,e?:Cell) => {
        const {revision,id} = td;
        const sd = nifi.cells.get(id);
        nifi.cells.set(td)
        if(sd && revision.version == sd.revision.version){
            console.info('=========== 没有发现版本变化 无需更新节点属性 ============')
            return false;
        }
        // 获取目标数据和原始数据并比较值的变化，取变化的值的集合
        const props:any = diff(pickData(td,KEYS),pickData(sd,KEYS));
        //
        console.info('节点更新属性集合 ===> ',props)
        if(props && Object.keys(props).length > 0){
            (e || nifi.graph?.getCellById(id))?.prop(props);
        }
        // 
        return true;
    }
    // 更新单个元素
    const refresh = async (cell:Cell) => {
        try {
            const res = await nifi.cells.getCell(cell);
            update(res,cell);
            return true;
        } catch (error) {
            ElMessage.error("更新算子失败 :: " + error)
            console.error(error)
            return false;
        }
    }

    const contextmenu = (cell:Cell,evt:MouseEvent) => {
        const vnode = h(ContextmenuElem,{cell,nifi})
        nifi.contextmenu.open(evt,vnode)
    }

    const edit = async (cell?:Cell) => {
        nifi.drawer.open();
        let vnode:any
        if(cell){
            await refresh(cell)
            vnode = h(FormElem, { nifi, cell })
        }else{
            vnode = h(FormElem,{nifi})
        }
        nifi.drawer.set(vnode)
    }

    const view = async (cell?:Cell) => {
        nifi.drawer.open();
        let vnode:any
        if(cell){
            await refresh(cell)
            vnode = h(FormElem, { nifi, cell, disabled:true})
        }else{
            vnode = h(FormElem,{nifi,disabled:true})
        }
        nifi.drawer.set(vnode)
    }
    // 自动刷新单个节点的数据的开关
    const togglePower = async (cell:Cell) => {
        // 获取当前开关状态
        let b = cell.prop('power')
        // 状态为 on 时，关闭开关，并停止刷新循环
        // 状态为 off 时 打开开关并开启自动刷新循环
        clearInterval(b)
        if(b > -1){
            b = -1;
        }
        else {
            b = setInterval(() => {
                // 更新节点数据
                refresh(cell)
            },5000)
            nifi.local.saveIntervalHandle(b);
        }
        cell.prop({power:b})
        // console.log('===>',b)
    }

    // 跳转
    const goto = (cell?:Cell) => {
        const id = cell?.id;
        if(id) {
            nifi.group.refresh(id)
        }
    }

    //
    const start = () => {}
    const stop = () => {}
    const enable = () => {}
    const disable = () => {}
    const clear = () => {}

    return {
        name,
        shape,
        //
        init,
        add,
        update,
        refresh,
        //
        edit,
        view,
        contextmenu,
        goto,
        togglePower,
    }
}